﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Xml;

namespace Common
{
    /// <summary>
    /// 给给各个类提供扩展函数的类
    /// </summary>
    public static class ExtensionMethods
    {
        /// <summary>
        /// 反序列化对象提供一个获取值的方法
        /// </summary>
        /// <typeparam name="T">要返回的值的类型</typeparam>
        /// <param name="info"></param>
        /// <param name="key">键</param>
        /// <returns></returns>
        public static T TryGetValue<T>(this SerializationInfo info, string key)
        {
            try
            {
                return (T)info.GetValue(key, typeof(T));
            }
            catch
            {
                return default(T);
            }
        }

        private static readonly object XmlLock = new object();
        public static string GetValue(this XmlDocument xmldoc, string filePath, string nodePath)
        {
            if (xmldoc == null)
                return null;//throw new ArgumentNullException("xmldoc");
            lock (XmlLock)
            {
                string temp = String.Empty;
                try
                {
                    xmldoc.Load(filePath);
                    var selectSingleNode = xmldoc.SelectSingleNode(nodePath);
                    if (selectSingleNode != null)
                        temp = selectSingleNode.InnerText;
                }
                catch
                {
                    return null;
                }
                return temp;
            }
        }

        /// <summary>
        /// 将时间转化成带毫秒的时间字符串
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string ToFullTimeString(this DateTime dateTime)
        {
            return dateTime.ToString("hh:mm:ss.fff");
        }

        /// <summary>
        /// 尝试从Dictionary中通过指定的键获取相应的值
        /// 如果不存在键或者值，那么将返回空
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static TValue TryGetValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
        {
            if (Equals(key, default(TKey))) return default(TValue);
            if (!dictionary.ContainsKey(key)) return default(TValue);
            return dictionary[key];
        }

        /// <summary>
        /// 尝试向Dictionary中添加一个键值对，如果已存在，则跳过
        /// 如果键为空，不抛出异常
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
        {
            if (Equals(key, default(TKey))) return;
            if (dictionary.ContainsKey(key)) return;
            dictionary.Add(key, value);
        }

        /// <summary>
        /// 尝试从Dictionary中移除一个元素，当键为空的时候，不抛出异常
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="key"></param>
        public static void TryRemove<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
        {
            if (Equals(key, default(TKey))) return;
            dictionary.Remove(key);
        }

        /// <summary>
        /// 不抛异常的添加一个List
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="lst"></param>
        /// <param name="targetList"></param>
        public static void AddRangeWithoutException<T>(this List<T> lst, IEnumerable<T> targetList)
        {
            if (lst == null)
            {
                return;
            }
            lst.AddRange(targetList);
        }

        public static string ParseSqlCommand(this string s)
        {
            if (s.IsNullOrEmpty())
            {
                return s;
            }
            return s.Replace("'", "''");
        }

        /// <summary>
        /// 字符串是否为空或者只包含空字符
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string s)
        {
            return string.IsNullOrEmpty(s);
        }

        public static bool IsNumber(this string s)
        {
            return !s.IsNullOrEmpty() && s.All(c => c >= '0' && c <= '9');
        }

        /// <summary>
        /// 将字符串转化为阿拉伯数字,如果不是
        /// 数字的话，那么返回0
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int ParseInt(this string str)
        {
            try
            {
                return Convert.ToInt32(str);
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 判断一个List是否为null或者没有任何元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="lst"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty<T>(this List<T> lst)
        {
            return lst == null || lst.Count == 0;
        }

        /// <summary>
        /// 浮点数是不是非数字
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public static bool IsNaN(this double x)
        {
            return double.IsNaN(x);
        }
    }
}
